﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace QuickStart.UnitTests
{
	public abstract class CustomerRepositoryFixture
	{
		protected abstract ICustomerRepository CreateRepository();

		[TestMethod]
		public void ShouldCreateAndGetCustomer()
		{
			var repository = CreateRepository();
			var customer = new Customer { FirstName = "Joe", LastName = "Doe" };

			var id = repository.Create(customer);

			Assert.AreEqual(id, customer.Id);

			var saved = repository.Get(id);

			Assert.AreEqual(id, saved.Id);
			Assert.AreEqual(customer.FirstName, saved.FirstName);
			Assert.AreEqual(customer.LastName, saved.LastName);
		}

		[TestMethod]
		public void ShouldCreateUpdateAndGetCustomer()
		{
			var repository = CreateRepository();
			var customer = new Customer { FirstName = "Joe", LastName = "Doe" };

			var id = repository.Create(customer);
			Assert.AreEqual(id, customer.Id);

			customer.LastName = "Smith";
			var wasSaved = repository.Update(customer);
			Assert.IsTrue(wasSaved);

			var saved = repository.Get(id);

			Assert.AreEqual(id, saved.Id);
			Assert.AreEqual("Smith", customer.LastName);
		}

		[TestMethod]
		public void ShouldGetAllCustomers()
		{
			var repository = CreateRepository();
			repository.Create(new Customer { FirstName = "Joe", LastName = "Doe" });
			repository.Create(new Customer { FirstName = "Sarah", LastName = "Smith" });

			var all = repository.GetAll();

			Assert.AreEqual(2, all.Count());
		}

		[TestMethod]
		public void UpdateNonExistentCustomerReturnsFalse()
		{
			var repository = CreateRepository();

			var result = repository.Update(new Customer { Id = "1", FirstName = "Joe", LastName = "Doe" });

			Assert.IsFalse(result);
		}

		[TestMethod]
		public void DeleteNonExistentCustomerReturnsFalse()
		{
			var repository = CreateRepository();

			var result = repository.Delete(new Customer { Id = "1", FirstName = "Joe", LastName = "Doe" });

			Assert.IsFalse(result);
		}

		[TestMethod]
		public void DeleteNonExistentCustomerIdReturnsFalse()
		{
			var repository = CreateRepository();

			var result = repository.Delete("1");

			Assert.IsFalse(result);
		}

		[TestMethod]
		public void FindByNameMatchesPartialFirstNameCaseInsensitive()
		{
			var repository = CreateRepository();
			repository.Create(new Customer { FirstName = "Joe", LastName = "SMITH" });
			repository.Create(new Customer { FirstName = "Joseph", LastName = "Smith" });

			var result = repository.FindByName("jo");

			Assert.AreEqual(2, result.Count());
		}

		[TestMethod]
		public void FindByNameMatchesPartialLastNameCaseInsensitive()
		{
			var repository = CreateRepository();
			repository.Create(new Customer { FirstName = "Joe", LastName = "SMITH" });
			repository.Create(new Customer { FirstName = "Joseph", LastName = "Smith" });

			var result = repository.FindByName("mI");

			Assert.AreEqual(2, result.Count());
		}
	}
}
